package com.happy_hao.user.service.UserServiceImpl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.happy_hao.user.common.Result;
import com.happy_hao.user.dto.CreateUserRequest;
import com.happy_hao.user.dto.UpdateUserRequest;
import com.happy_hao.user.exception.ServiceException;
import com.happy_hao.user.mapper.*;
import com.happy_hao.user.po.*;
import com.happy_hao.user.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private GroupUserMapper groupUserMapper;

    @Resource
    private GroupPermissionMapper groupPermissionMapper;

    @Override
    public Result createUser(CreateUserRequest createUserRequest) {

        String identifier = createUserRequest.getIdentifier();
        User user1 = (User) readUserByIdentifier(identifier).getData().get("user");
        if (user1 != null) {
            throw new ServiceException("用户名/邮箱/电话已被注册");
        }
        String encryptedPassword = createUserRequest.getEncryptedPassword();
        User user = new User();
        user.setUserId(IdUtil.getSnowflakeNextId());
        String e = RandomUtil.randomString(19) + "e";
        while (this.getOne(new QueryWrapper<User>().eq("user_name", e)) != null) {
            e = RandomUtil.randomString(19) + "e";
        }
        if (isEmail(identifier)) {
            user.setUserName(e);
            user.setEmail(identifier);
        } else if (isPhone(identifier)) {
            user.setUserName(e);
            user.setPhone(identifier);
        } else {
            user.setUserName(identifier);
        }
        user.setEnabled(true);
        user.setCreateAt(new Date());
        user.setUpdateAt(user.getCreateAt());
        GroupUser groupUser = new GroupUser();
        groupUser.setGuId(IdUtil.getSnowflakeNextId());
        groupUser.setUserId(user.getUserId());
        groupUser.setGroupId(groupMapper.selectOne(new QueryWrapper<Group>().eq("group_name", "USER")).getGroupId());
        groupUser.setCreateAt(new Date());
        groupUser.setUpdateAt(user.getCreateAt());
        if (encryptedPassword == null || encryptedPassword.isEmpty()) {
            user.setPassword("$shiro2$argon2id$v=19$t=1,m=65536,p=4$pfeySka38rM8ZRJXQfoozw$Pt2AXqF2s7QYl4GrwOGlCy25SqWvZKZe5vU4UrnwJGU");
            this.save(user);
            groupUserMapper.insert(groupUser);
            return Result.success().message("初始密码w12345678");
        }
        user.setPassword(encryptedPassword);
        this.save(user);
        groupUserMapper.insert(groupUser);
        return Result.success();
    }

    @Override
    public Result readUserById(Long id) {
        User user = userMapper.selectById(id);
        return Result.success().data("user", user);
    }

    @Override
    public Result updateUser(UpdateUserRequest updateUserRequest) {

        User principal = (User) readUserById(updateUserRequest.getId()).getData().get("user");
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", principal.getUserId());

        if (updateUserRequest.getUserName() != null) {
            if (principal.getUserName().equals(updateUserRequest.getUserName())) {
                throw new ServiceException("用户名未更改");
            }
            if (userMapper.selectOne(new QueryWrapper<User>().eq("user_name", updateUserRequest.getUserName())) != null) {
                throw new ServiceException("用户名已被使用");
            }
            updateWrapper.set("user_name", updateUserRequest.getUserName());
        }
        if (updateUserRequest.getEmail() != null) {
            if (principal.getEmail()!=null) {
                if (principal.getEmail().equals(updateUserRequest.getEmail())) {
                    throw new ServiceException("邮箱未更改");
                }
                if (userMapper.selectOne(new QueryWrapper<User>().eq("email", updateUserRequest.getEmail())) != null) {
                    throw new ServiceException("邮箱已被使用");
                }
            }

            updateWrapper.set("email", updateUserRequest.getEmail());
        }
        if (updateUserRequest.getPhone() != null) {
            if (principal.getPhone()!=null) {
                if (principal.getPhone().equals(updateUserRequest.getPhone())) {
                    throw new ServiceException("电话未更改");
                }
                if (userMapper.selectOne(new QueryWrapper<User>().eq("phone", updateUserRequest.getPhone())) != null) {
                    throw new ServiceException("电话已被使用");
                }
            }

            updateWrapper.set("phone", updateUserRequest.getPhone());
        }
        if (updateUserRequest.getNickname() != null) {
            updateWrapper.set("nickname", updateUserRequest.getNickname());
        }
        if (updateUserRequest.getGender() != null) {
            updateWrapper.set("gender", updateUserRequest.getGender());
        }
        if (updateUserRequest.getDescription() != null) {
            updateWrapper.set("description", updateUserRequest.getDescription());
        }
        updateWrapper.set("update_at", new Date());
        // 调用 update 方法更新数据
        userMapper.update(null, updateWrapper);
        return Result.success().message("修改成功");
    }

    @Override
    public Result deleteUser(Long id) {
        User principal = (User) readUserById(id).getData().get("user");
        QueryWrapper<GroupUser> queryWrapper = new QueryWrapper<>();
        groupUserMapper.delete(queryWrapper.eq("user_id", principal.getUserId()));
        userMapper.deleteById(principal.getUserId());
        return Result.success().message("注销成功");
    }

    @Override
    public Result readUserByIdentifier(String identifier) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        User user;
        // 判断标识符是用户名、邮箱还是手机号
        if (isEmail(identifier)) {
            user = userMapper.selectOne(queryWrapper.eq("email", identifier));
        } else if (isPhone(identifier)) {
            user = userMapper.selectOne(queryWrapper.eq("phone", identifier));
        } else {
            user = userMapper.selectOne(queryWrapper.eq("user_name", identifier));
        }
        if (Objects.isNull(user)) {
            return Result.error().data("user", null);
        }
        user.setGroups(getGroupsByUserId(user.getUserId()));
        List<Permission> permissions = new ArrayList<>();
        for(Group group : user.getGroups()) {
            permissions.addAll(getPermissionsByGroupId(group.getGroupId()));
        }
        user.setPermissions(permissions);
        return Result.success().data("user", user);
    }

    public boolean isEmail(String identifier) {
        return identifier.contains("@");
    }

    public boolean isPhone(String identifier) {
        return identifier.matches("^\\d+$");
    }

    public List<Group> getGroupsByUserId(Long userId) {
        QueryWrapper<GroupUser> groupUserQueryWrapper = new QueryWrapper<>();
        groupUserQueryWrapper.eq("user_id", userId);
        List<GroupUser> groupUsers = null;
        if (groupUserMapper != null) {
            groupUsers = groupUserMapper.selectList(groupUserQueryWrapper);
        }
        List<Long> groupIds = new ArrayList<>();
        if (groupUsers != null) {
            for (GroupUser groupUser : groupUsers) {
                groupIds.add(groupUser.getGroupId());
            }
        }
        QueryWrapper<Group> groupQueryWrapper = new QueryWrapper<>();
        groupQueryWrapper.in("group_id", groupIds);
        if (groupMapper != null) {
            return groupMapper.selectList(groupQueryWrapper);
        }
        return List.of();
    }

    private List<Permission> getPermissionsByGroupId(Long groupId) {
        QueryWrapper<GroupPermission> groupPermissionQueryWrapper = new QueryWrapper<>();
        groupPermissionQueryWrapper.eq("group_id", groupId);
        List<GroupPermission> groupPermissions = null;
        if (groupPermissionMapper != null) {
            groupPermissions = groupPermissionMapper.selectList(groupPermissionQueryWrapper);
        }
        List<Long> permissionIds = new ArrayList<>();
        if (groupPermissions != null) {
            for (GroupPermission groupPermission : groupPermissions) {
                permissionIds.add(groupPermission.getPermissionId());
            }
        }
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.in("permission_id", permissionIds);
        if (permissionMapper != null) {
            return permissionMapper.selectList(permissionQueryWrapper);
        }
        return List.of();
    }
}
